package com.zmn.oms.task.listener;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.zmn.common.utils.collection.CollectionUtil;
import com.zmn.common.utils.number.NumberUtil;
import com.zmn.consts.GlobalConsts;
import com.zmn.dms.common.enums.coup.ThirdPlatEnum;
import com.zmn.manager.mq.annotation.AliyunMQHandler;
import com.zmn.manager.mq.annotation.AliyunMQListener;
import com.zmn.manager.redis.RedisManager;
import com.zmn.manager.redis.lock.DistributedLock;
import com.zmn.manager.redis.lock.DistributedLockUtils;
import com.zmn.oms.common.constant.LockConsts;
import com.zmn.oms.common.constant.MessageQueueTagConsts;
import com.zmn.oms.common.constant.OrderStatusConsts;
import com.zmn.oms.common.constant.RedisKeyConsts;
import com.zmn.oms.model.entity.discount.OrderDiscount;
import com.zmn.oms.model.entity.work.OrderWork;
import com.zmn.oms.services.interfaces.discount.OrderDiscountService;
import com.zmn.oms.services.interfaces.work.OrderWorkAmountService;
import com.zmn.oms.services.interfaces.work.OrderWorkService;
import com.zmn.oms.zmn.business.interfaces.discount.ChannelDiscountService;
import com.zmn.oms.zmn.business.interfaces.work.autoflow.WorkFlowContextBService;
import com.zmn.pay.common.constant.PayConsts;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * 类描述：优惠监听
 * @author heciqi
 * @date 2021/12/1 14:02
 */
@Slf4j
@AliyunMQListener(topic = "${spring.mq.topic.dms}")
@Component
public class DmsDiscountListener {

	@Autowired
	private OrderDiscountService orderDiscountService;
	@Autowired
	private OrderWorkService orderWorkService;
	@Autowired
	private OrderWorkAmountService orderWorkAmountService;
	@Autowired
	private ChannelDiscountService channelDiscountService;

	@Resource
	private RedisManager redisManager;

	/**
	 * 第三个获取售价监听
	 * @param message
	 */
	@AliyunMQHandler(tags = MessageQueueTagConsts.DMS_THIRD_COUPON_SALE_PRICE)
	public void thirdCouponSalePrice(String message) {
		log.info("#mq#DmsDiscountListener#thirdConponSalePrice message:{}", message);
		JSONObject data = JSON.parseObject(message);
		Long orderId = data.getLong("orderId");
		String couponCode = data.getString("couponCode");
		Integer salePrice = data.getInteger("salePrice");
		log.info("更新售价-开始 orderId：{} couponCode:{} salePrice：{}", orderId, couponCode, salePrice);
		String lockKey = String.format("%s", orderId);
		DistributedLock lock = DistributedLockUtils.build(LockConsts.LOCK_ORDER_DISCOUNT_SELLAMOUNT + lockKey, 10);
		if (lock.tryLock()) {
			try {
				this.updateConponSalePrice(orderId, couponCode, salePrice);
			} catch (Exception e) {
				log.error("更新售价异常:" + e.getMessage(),e);
			} finally {
				lock.unlock();
			}
		}
	}

	/**
	 * 第三个获取售价监听
	 * @param message
	 */
	@AliyunMQHandler(tags = MessageQueueTagConsts.ZMN_TAG_DMS_MEITUAN_RECEIPT_COUP)
	public void updateMeituanWriteOffStatus(String message) {
		log.info("#mq#DmsDiscountListener#更新美团优惠券 message:{}", message);
		try {
			JSONObject data = JSON.parseObject(message);
			Long orderId = data.getLong("orderId");
			String couponCode = data.getString("couponCode");
			channelDiscountService.modifyMeiTuanChannelDiscount(orderId, couponCode);
		} catch (Exception e) {
			e.printStackTrace();
			log.error("更新美团优惠券状态异常：【{}】", e.getMessage());
		}
	}

	private void updateConponSalePrice(Long orderId, String couponCode,Integer salePrice){

		OrderWork orderWork = orderWorkService.findOrderWorkByKeySrcMaster(orderId, orderId);
		if (Objects.isNull(orderWork)) {
			log.error("更新售价-订单不存在==>{}",orderId);
			return;
		}
		if (orderWork.getStatus() >= OrderStatusConsts.WORK_STATUS_COMPLETE) {
			log.error("更新售价-订单已完成，不更新==>{}",orderId);
			return;
		}

		if (Objects.equals(orderWork.getMasterPayStatus(), PayConsts.PAY_STATUS_DONE)) {
			log.error("更新售价-订单已支付尾款，不更新==>{}",orderId);
			return;
		}

		List<OrderDiscount> orderDiscountList = orderDiscountService.listByOrderIdSrcMaster(orderId);
		if (CollectionUtil.isNullOrEmpty(orderDiscountList)) {
			log.error("更新售价-为发现优惠，不更新==>{}",orderId);
			return;
		}

		List<OrderDiscount> collect = orderDiscountList.stream()
				.filter(e -> Objects.equals(e.getItemCode(), couponCode)
						&& Objects.equals(e.getThirdCoupPlat(), ThirdPlatEnum.THIRD_COUP_TYPE_MT.getKey()))
				.collect(Collectors.toList());
		if (CollectionUtil.isNullOrEmpty(collect)) {
			log.error("更新售价-为发现匹配优惠{}，不更新==>{}", couponCode, orderId);
			return;
		}
		Integer sellAmount = collect.get(0).getSellAmount();
		if (NumberUtil.isNotNullOrZero(sellAmount)) {
			log.error("更新售价-已存在售价{}，不更新==>{}", sellAmount, orderId);
			return;
		}
		// 计算实际优惠金额
		Integer amount = collect.get(0).getAmount();
		salePrice = Optional.ofNullable(salePrice).orElse(0);
		Integer factAmount = amount - salePrice;// 实际优惠金额 = 优惠金额-售价
		if (factAmount < 0) {
			factAmount = 0;
		}
		OrderDiscount orderDiscount = new OrderDiscount();
		orderDiscount.setOrderId(orderId);
		orderDiscount.setThirdCoupPlat(ThirdPlatEnum.THIRD_COUP_TYPE_MT.getKey());
		orderDiscount.setSellAmount(salePrice);
		orderDiscount.setItemCode(couponCode);
		orderDiscount.setAmount(factAmount);
		orderDiscount.setUpdater("系统-更新售价");
		log.info("更新售价->{}", orderDiscount);
		Integer ret = orderDiscountService.updateSellAmount(orderDiscount);
		log.info("更新售价-成功{}，影响行：{}",orderId,ret);

		List<OrderDiscount> newOrderDiscount = orderDiscountService.listByOrderIdSrcMaster(orderId);
		int totalDiscount = newOrderDiscount.stream().mapToInt(e -> e.getAmount()).sum();
		OrderWork updateOrderWork = new OrderWork();
		updateOrderWork.setOrderId(orderId);
		updateOrderWork.setWorkId(orderId);
		updateOrderWork.setDiscountAmount(totalDiscount);
		if (NumberUtil.isNotNullOrZero(orderWork.getOriginalAmount())) {
			Integer refundAmount = Optional.ofNullable(orderWork.getRefundAmount()).orElse(0);// 退款总额
			int totalAmount = orderWork.getOriginalAmount() - totalDiscount - refundAmount;
			Integer depositAmount = Optional.ofNullable(orderWork.getDepositAmount()).orElse(0);// 定金
			Integer prepayAmount = Optional.ofNullable(orderWork.getPrepayAmount()).orElse(0);// 啄木鸟预收
			Integer channelPrepayAmount = salePrice;
			Integer masterAmount = totalAmount - depositAmount - prepayAmount - channelPrepayAmount;
			if (masterAmount < 0) {
				masterAmount = 0;
			}
			updateOrderWork.setChannelPrepayStatus(PayConsts.PAY_STATUS_DONE);
			updateOrderWork.setChannelPrepayAmount(channelPrepayAmount);
			updateOrderWork.setTotalAmount(totalAmount);
			updateOrderWork.setMasterAmount(masterAmount);
		}
		log.info("更新售价-金额修改->{}", JSON.toJSONString(updateOrderWork));
		orderWorkAmountService.updateDiscountAmount(updateOrderWork);
	}
}
